package com.gcloud.mesh.asset.dao;

import com.gcloud.framework.db.PageResult;
import com.gcloud.framework.db.dao.impl.JdbcBaseDaoImpl;
import com.gcloud.mesh.asset.entity.CloudResourceEntity;
import com.gcloud.mesh.asset.enums.AuthorityCloudResourceType;
import com.gcloud.mesh.asset.enums.CloudResourceType;
import com.gcloud.mesh.dcs.service.AuthorityService;
import com.gcloud.mesh.header.enums.AuthorityResourceClassification;
import com.gcloud.mesh.header.enums.AuthorityResourceType;
import com.gcloud.mesh.header.enums.ResourceSourceType;
import com.gcloud.mesh.header.msg.asset.PageCloudResourceMsg;
import com.gcloud.mesh.header.msg.dcs.ListByClassificationMsg;
import com.gcloud.mesh.header.vo.asset.CloudResourceItemVo;
import com.gcloud.mesh.header.vo.dcs.AuthorityVo;
import com.gcloud.mesh.utils.PageUtil;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Repository
public class CloudResourceDao extends JdbcBaseDaoImpl<CloudResourceEntity, String>{
	
	@Autowired
	private AuthorityService authorityService;
	
	public <E> PageResult<E> page(PageCloudResourceMsg msg, Class<E> clazz) {
		StringBuffer sql = new StringBuffer();
		sql.append(" select r.*, d.name AS datacenterName from asset_cloud_resources r LEFT JOIN asset_datacenters d ON d.id = r.datacenter_id");
		sql.append(" where 1 = 1");
		
		
		List<Object> values = new ArrayList<Object>();
		if(StringUtils.isNotEmpty(msg.getName())) {
			sql.append(" and r.name like concat('%', ?, '%')");
			values.add(msg.getName());
		}
		
		if(msg.getType() != null) {
			sql.append(" and r.type = ?");
			values.add(msg.getType());
		}
		
		if(StringUtils.isNotEmpty(msg.getDatacenterId())) {
			sql.append(" and r.datacenter_id = ?");
			values.add(msg.getDatacenterId());
		}
		
		checkResourceAuthority(sql);
		
		sql.append(" order by r.create_time desc ");
		return this.findBySql(sql.toString(), values, msg.getPageNo(), msg.getPageSize(), clazz);	
	}
	
	public PageResult<CloudResourceItemVo> page(PageCloudResourceMsg msg) {
		List<AuthorityVo> authorities = listAuthority(AuthorityResourceClassification.CLOUD.getName());
		List<String> filterAuthorities = authorities.stream()
				.filter( s -> !s.getEnabled())
				.map( s -> s.getId())
				.collect(Collectors.toList());
		
		List<Integer> types = new ArrayList<Integer>();
		
		if(msg.getType() == null) {
			types.add(CloudResourceType.HUAWEI.getType());
			types.add(CloudResourceType.ALI.getType());
			types.add(CloudResourceType.K8S.getType());
		}else if(msg.getType().equals(0)){
			//虚拟机的
			types.add(CloudResourceType.HUAWEI.getType());
			types.add(CloudResourceType.ALI.getType());
		}else{
			types.add(msg.getType());
		}	
		
		List<CloudResourceItemVo> resources = listCloudResource(msg.getDatacenterId(), msg.getName(), types);
		List<CloudResourceItemVo> filterResources = resources.stream()
				.filter( s -> {
					String id = CloudResourceType.getByType(s.getType()).getEnName();
					if(ResourceSourceType.SYNC.getName().equals(s.getFrom()) && filterAuthorities.contains(id)) {
						return false;
					}
					return true;
				})
				.collect(Collectors.toList());
		return PageUtil.page(msg.getPageNo(), msg.getPageSize(), filterResources);	
	}
	
	private StringBuffer checkResourceAuthority(StringBuffer sql) {

		ListByClassificationMsg msg = new ListByClassificationMsg();
		msg.setClassification(AuthorityResourceClassification.CLOUD.getName());
		List<AuthorityVo> authorities = null;
		try {
			authorities = authorityService.listByClassification(msg);
		}catch(Exception e) {
			
		}
		String template = " and type != %d ";
		if(authorities != null) {
			for(AuthorityVo vo: authorities) {
				if(!vo.getEnabled()) {
					int type = AuthorityCloudResourceType.getByResource(AuthorityResourceType.getByName(vo.getId())).getCloudResource().getType();
					sql.append(String.format(template, type));
				}
			}
		}

		return sql;
	}
	
	public int count(Integer type) {
		StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM asset_cloud_resources WHERE 1=1");
		if (type != null) {
			sql.append(" AND type=").append(type);
		}
		return this.countBySql(sql.toString(), new ArrayList<Object>());
	}
	
	public List<AuthorityVo> listAuthority(String classification) {
		ListByClassificationMsg msg = new ListByClassificationMsg();
		msg.setClassification(classification);
		List<AuthorityVo> authorities = null;
		try {
			authorities = authorityService.listByClassification(msg);
		}catch(Exception e) {
			log.error("[CloudResourceDao][checkResourceAuthority] AuthorityService服务的listByClassification异常：{}", e.getMessage());
		}
		return authorities;
	}
	
	private List<CloudResourceItemVo> listCloudResource(String datacenterId, String name, List<Integer> types) {
		StringBuffer sql = new StringBuffer();
		sql.append(" select r.*, d.name AS datacenterName from asset_cloud_resources r LEFT JOIN asset_datacenters d ON d.id = r.datacenter_id");
		sql.append(" where 1 = 1");		
		
		List<Object> values = new ArrayList<Object>();
		if(StringUtils.isNotEmpty(name)) {
			sql.append(" and r.name like concat('%', ?, '%')");
			values.add(name);
		}
			
		if(types != null && types.size() > 0) {
			StringBuffer includeType = new StringBuffer();
			for(Integer i: types) {
				includeType.append(i + ",");
			}
			sql.append(" and r.type in ( " + includeType.substring(0, includeType.length() -1) + " )");
			
		}
		
		if(StringUtils.isNotEmpty(datacenterId)) {
			sql.append(" and r.datacenter_id = ?");
			values.add(datacenterId);
		}
		sql.append(" order by r.create_time desc ");
		
		List<CloudResourceItemVo> res = this.findBySql(sql.toString(), values, CloudResourceItemVo.class);
		return res;	
	}
	
	
}
